class Timer {
    constructor() {
        this.paused = true
        this.queue = new Map()
        this.usingRAF = false

        Reflect.defineProperty(this, "useRAF", {
            set: function (value) {
                Reflect.set(this, "usingRAF", value)
                value ? Timer.RAF.enable() : Timer.RAF.disable()
            }
        })
    }

    setTimeout(fn, delay, id = Symbol("timeoutID")) {
        this.queue.set(id, {
            fn: fn,
            type: 0,
            paused: 0,
            elapsed: 0,
            delay: delay
        })
        return id
    }

    clearTimeout(id) {
        return this.delete(id)
    }

    setInterval(fn, delay, id = Symbol("intervalID")) {
        this.queue.set(id, {
            fn: fn,
            type: 1,
            paused: 0,
            elapsed: 0,
            delay: delay
        })
        return id
    }

    clearInterval(id) {
        return this.delete(id)
    }

    // 修改指定id的 delay/fn
    set(id, config = {}) {
        let item = this.queue.get(id) || {}
        for (let key in config) {
            item[key] = config[key]
        }
        return true
    }

    // 删除 queue 上的成员
    delete(id) {
        return this.queue.delete(id)
    }

    // 暂停指定id
    pause(id) {
        id === undefined ? this.pauseAll() : (this.queue.get(id) && (this.queue.get(id).paused = 1))
        return true
    }

    // 恢复指定id
    resume(id) {
        return this.play(id)
    }

    // 播放指定id
    play(id) {
        id === undefined ? this.playAll() : (this.queue.get(id) && (this.queue.get(id).paused = 0))
        return true
    }

    clean() {
        this.queue = new Map()
        return true
    }

    // 暂停全部 id
    pauseAll() {
        this.queue.forEach((item) => item.paused = 1)
        return true
    }

    // 播放全部 id
    playAll() {
        this.queue.forEach((item) => item.paused = 0)
        return true
    }

    // 重置 elapsed 为 0
    reset(id) {
        id === undefined ? this.resetAll() : (this.queue.get(id).elapsed = 0)
    }

    // 重置所有的 elapsed 为 0
    resetAll() {
        this.queue.forEach(function (item) { item.elapsed = 0 })
    }

    // tick
    tick(delta) {
        this.paused || this.updateQueue(delta)
    }

    updateQueue(delta) {
        this.queue.forEach((item, id) => {
            if (item.paused === 1) return
            item.elapsed += delta
            if (item.elapsed >= item.delay) {
                item.fn()
                item.type === 0 ? this.delete(id) : (item.elapsed = 0)
            }
        })
    }

    // 状态更新
    update() {
        // 第一次调用 update 时主动停用原生接口
        this.useRAF = false
        // 下面是真正的 update
        this.update = (delta) => {
            if (this.usingRAF) return
            this.tick(delta)
        }
    }

}

export default () => {
    let timer = new Timer()
    class AnimationFrame {
        constructor() {
            this.time = 0
            this.auto = this.auto.bind(this)
        }

        auto(elapsed) {
            timer.tick(elapsed - this.time)
            this.time = elapsed
            this.id = requestAnimationFrame(this.auto)
        }

        enable() {
            timer.paused = false
            this.id = requestAnimationFrame(this.auto)
        }

        disable() {
            cancelAnimationFrame(this.id)
        }
    }
    Timer.RAF = new AnimationFrame()
    timer.useRAF = true
    return timer
}
